import { oTools_PinyinEngine } from "./tools_pinyin";

function oToolsEngine(engine) {
  this.engine = engine;
  this.base64 = Dan.Base64;
  //汉子首字母换拼音
  this.pinyin = new oTools_PinyinEngine(this);
}

oToolsEngine.prototype = {
  // 获取前端八爪鱼框架配置，此处因为是初始化所以不能使用tips、template引擎。
  md5: function(val) {
    return Md5(val)
      .toString()
      .toLocaleUpperCase();
  },
  guid: function() {
    let key = this.md5(new Date().getTime() + "M&J" + new Date().getTime());
    if (key.length == 32) {
      key =
        key.substring(0, 6) +
        "-" +
        key.substring(6, 11) +
        "-" +
        key.substring(11, 16) +
        "-" +
        key.substring(16, 21) +
        "-" +
        key.substring(21, 26) +
        "-" +
        key.substring(26, 32);
    }
    return key.toLocaleUpperCase();
  },
  IsNullOrEmpty: function(val) {
    if (val != null && val.toString() != "") {
      return false;
    }
    return true;
  },
  // 是否是移动端
  isMobile: function() {
    let userAgentInfo = navigator.userAgent;
    let mobileAgents = [
      "Android",
      "iPhone",
      "SymbianOS",
      "Windows Phone",
      "iPad",
      "iPod"
    ];
    let mobile_flag = false;
    //根据userAgent判断是否是手机
    for (let v = 0; v < mobileAgents.length; v++) {
      if (userAgentInfo.indexOf(mobileAgents[v]) > 0) {
        mobile_flag = true;
        break;
      }
    }
    let screen_width = window.screen.width;
    let screen_height = window.screen.height;
    //根据屏幕分辨率判断是否是手机
    // if (screen_width < 500 && screen_height < 800) {
    //     mobile_flag = true;
    // }
    //  当移动端的时候，才去检测他的屏幕大小  1024，1366 暂时将宽高改成ipad大小
    // if (mobile_flag) {
    if (screen_width < 1025 && screen_height < 1367) {
      mobile_flag = true;
    }
    // }
    return mobile_flag;
  },
  // 是否是小程序
  isApplet() {
    let userAgent = navigator.userAgent.toLowerCase();
    return new Promise(async res => {
      // 判断是否具备小程序识别标签
      if (
        userAgent.indexOf("micromessenger") == -1 &&
        userAgent.indexOf("alipayclient") == -1
      ) {
        res(false);
      } else {
        if (window.my) {
          let isAliPayApplet = await this.engine.applet.isAliPayApplet();
          res(isAliPayApplet);
        } else {
          let isWeChatApplet = await this.engine.applet.isWeChatApplet();
          res(isWeChatApplet);
        }
      }
    });
  },
  isNumber: function(value) {
    return typeof value === "number" && !isNaN(value);
  },
  // 转换八爪鱼特色代码，正则提取，主要支持#{param=xxxx}，
  parseScript: function(data) {
    if (!this.IsNullOrEmpty(data)) {
      // console.log("source.data.value: " + data + ", router.query:" + JSON.stringify(this.engine.router.get().query));
      let o = this;
      // 字符串化，java不能自转，且复选控件返回是数组格式，此处必须转换为字符串，否则保存都有问题。
      let parseData = data.toString();
      let regex = /\#{(.+?)\}/g; // {} 花括号，大括号
      // 返回的是数组，采用Jq循环
      $(parseData.match(regex)).each(function(index, item) {
        // 得到类型
        let type = item.split("{")[1].split("=")[0];
        let value = item.split("=")[1].split("}")[0];
        // 解析URL参数
        // console.log(type + "," + value);
        if (type == "param") {
          value = o.engine.router.get().query[value];
          // 如果未匹配到，则返回空，匹配失败。
          value = value == undefined ? "" : value;
          parseData = parseData.replace(item, value);
        }
        // xxxxx。
        else if (type == "xxxx") {
        }
      });
      // console.log(parseData.match(regex));
      return parseData;
    }
    return data;

    // JavaScript正则表达式在线测试工具：
    // http://tools.jb51.net/regex/javascript
    // 正则表达式在线生成工具：
    // http://tools.jb51.net/regex/create_reg
    // var str="123{xxxx}456[我的]789123[你的]456(1389090)789";
    // var regex1 = /\((.+?)\)/g;  // () 小括号
    // var regex2 = /\[(.+?)\]/g;  // [] 中括号
    // var regex3 = /\{(.+?)\}/g; // {} 花括号，大括号
    // console.log(str.match(regex1));
    // console.log(str.match(regex2));
    // console.log(str.match(regex3));
  },
  // 适配于八抓鱼数据源的Cell数据
  parseCell: function(data, name) {
    // 对象不能为空
    if (!this.IsNullOrEmpty(data.cellData)) {
      let findList = $.grep(data.cellData, function(item) {
        return item.name == name; //筛选出当前数据列数据
      });
      // alert(JSON.stringify(linkColumn));
      if (findList.length == 1) {
        // 赋值
        return findList[0];
      }
    }
    return null;
  },
  parseQuery: function(name) {
    let query = this.engine.router.get().query;
    return query[name];
  },
  date: function(fmt) {
    return this.dateFormat(new Date(), fmt);
  },
  dateFormatToString: function(date, fmt) {
    return this.dateFormat(new Date(date), fmt);
  },
  // 获取日期
  dateFormat: function(date, fmt) {
    // 对Date的扩展，将 Date 转化为指定格式的String
    // 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符，
    // 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
    // 例子：
    // (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
    // (new Date()).Format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18
    // let date = new Date();
    let o = {
      "M+": date.getMonth() + 1, //月份
      "d+": date.getDate(), //日
      "H+": date.getHours(), //小时
      "m+": date.getMinutes(), //分
      "s+": date.getSeconds(), //秒
      "q+": Math.floor((date.getMonth() + 3) / 3), //季度
      S: date.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt))
      fmt = fmt.replace(
        RegExp.$1,
        (date.getFullYear() + "").substr(4 - RegExp.$1.length)
      );
    for (let k in o)
      if (new RegExp("(" + k + ")").test(fmt))
        fmt = fmt.replace(
          RegExp.$1,
          RegExp.$1.length == 1
            ? o[k]
            : ("00" + o[k]).substr(("" + o[k]).length)
        );
    return fmt;
  },
  // 时间差返回 秒，兼容苹果IOS系统，苹果只支持/，不支持-。
  dateDifferenceToSecond: function(sDate, eDate) {
    // 格式化
    if (this.IsNullOrEmpty(sDate)) {
      sDate = new Date().getTime();
    } else if (Date.parse(sDate)) {
      sDate = new Date(Date.parse(sDate)).getTime();
    } else {
      sDate = new Date(sDate.replace(/-/g, "/")).getTime();
    }
    if (this.IsNullOrEmpty(eDate)) {
      eDate = new Date().getTime();
    } else if (Date.parse(eDate)) {
      eDate = new Date(Date.parse(eDate)).getTime();
    } else {
      eDate = new Date(eDate.replace(/-/g, "/")).getTime();
    }

    // 逻辑操作，先得到秒
    let diff = (eDate - sDate) / 1000;

    return diff;
  },
  // 时间差返回 人类语义化
  dateDifference: function(sDate, eDate) {
    // 逻辑操作，先得到秒
    let diff = this.dateDifferenceToSecond(sDate, eDate);
    // 如果大于60秒，则显示分钟逻辑
    if (diff > 60) {
      // 如果大于60分钟，则显示小时逻辑
      diff = diff / 60;
      if (diff > 60) {
        diff = diff / 60;
        if (diff > 24) {
          diff = diff / 24;
          diff = parseInt(diff) + " 天";
        } else {
          diff = parseInt(diff) + " 小时";
        }
      } else {
        diff = parseInt(diff) + " 分钟";
      }
    } else {
      diff = parseInt(diff) + "秒";
    }

    return diff;
  },
  // 日期加减计算 返回 日期对象
  dateCompute: function(date, type, value) {
    let newDate = new Date();
    if (!this.IsNullOrEmpty(date)) {
      // 判断是否为日期对象，如果是日期就转成字符串。
      if (Date.parse(date)) {
        date = this.dateFormat(date, "yyyy/MM/dd HH:mm:ss");
      }
      // 格式化日期
      newDate = new Date(date.replace(/-/g, "/"));
    }

    if (type == "d") {
      newDate = newDate.setDate(newDate.getDate() + value);
    } else if (type == "m") {
      newDate = newDate.setMonth(newDate.getMonth() + value);
    } else if (type == "y") {
      newDate = newDate.setFullYear(newDate.getFullYear() + value);
    } else if (type == "h") {
      newDate = newDate.setHours(newDate.getHours() + value);
    } else if (type == "m") {
      newDate = newDate.setMinutes(newDate.getMinutes() + value);
    } else if (type == "s") {
      newDate = newDate.setSeconds(newDate.getSeconds() + value);
    }

    // 返回日期对象
    return new Date(newDate);
  },
  // 指定日期的当年第几周
  weekData: function(date) {
    let today = new Date(date);
    let firstDay = new Date(today.getFullYear(), 0, 1);
    let dayOfWeek = firstDay.getDay();
    let spendDay = 1;
    if (dayOfWeek != 0) {
      spendDay = 7 - dayOfWeek + 1;
    }
    firstDay = new Date(today.getFullYear(), 0, 1 + spendDay);
    let d = Math.ceil((today.valueOf() - firstDay.valueOf()) / 86400000);
    let result = Math.ceil(d / 7);
    return result;
  },
  // 今日属于一年第几周
  weekDataForToday: function() {
    return this.weekData(new Date());
  },
  // 指定日期是周几
  weekName: function(date, type) {
    let today = new Date(date);
    type = type || 1;

    let days = today.getDay();
    let week;

    switch (days) {
      case 1:
        week = type == 1 ? "星期一" : "周一";
        break;
      case 2:
        week = type == 1 ? "星期二" : "周二";
        break;
      case 3:
        week = type == 1 ? "星期三" : "周三";
        break;
      case 4:
        week = type == 1 ? "星期四" : "周四";
        break;
      case 5:
        week = type == 1 ? "星期五" : "周五";
        break;
      case 6:
        week = type == 1 ? "星期六" : "周六";
        break;
      case 0:
        week = type == 1 ? "星期天" : "周日";
        break;
    }
    return week;
  },
  // 今天是周几
  weekNameForToday: function() {
    return this.weekName(new Date());
  },
  // 白忙活一场。。。毫无意义。。。fuck
  // 更新对象，精确到底层变量，如果是数组或对象直接[]、= 赋值的话 vue 不认。。。，object是将被更新的数据，update是更新数据，如果update中的数据object没有，则直接push，有则递归更新。
  updateObject: function(object, update) {
    this.engine.tips.debug(
      "[Update Object] Original:" + JSON.stringify(object)
    );
    this.engine.tips.debug("[Update Object] Update:" + JSON.stringify(update));
    // 循环当前集合
    for (let param in update) {
      // https://blog.csdn.net/zjy_android_blog/article/details/81023177
      // 判断类型，狸猫换太子
      let checkPrototype = Object.prototype.toString;
      // 判断js 7种数据类型 【字符串、数字、布尔、数组、对象、Null、Undefined】
      let type = checkPrototype.call(update[param]);
      // 如果是数组或者集合，则进行完整替换或直接传入。
      if (type.indexOf("Array") != -1 || type.indexOf("Object") != -1) {
        // 如果原始对象不存在，则直接完整覆盖。
        if (checkPrototype.call(object[param]).indexOf("Undefined") != -1) {
          this.engine.vue.$set(object, param, update[param]);
        }
        // 如果存在数组，则进去一个个替换，总之vue更新只能到最底层变量更新才行。fuck。。。
        else {
          this.updateObject(object[param], update[param]);
        }
      }
      // else if (type.indexOf("Null") != -1) {
      //
      // }
      // else if (type.indexOf("Undefined") != -1) {
      //
      // }
      // 剩余6种可以直接比较。
      else {
        // 通过原型判断 Undefined 因为 (undefined == null) = true 故 找不到undefined说明当前属性存在于原始对象中，则执行更新操作。
        if (checkPrototype.call(object[param]).indexOf("Undefined") == -1) {
          // 哪怕存在，如果没有改变也不发起更新操作。
          if (object[param] != update[param]) {
            object[param] = update[param];
            // object[param].splice(update[param].length);
            // this.engine.vue.$set(object, param, update[param]);
            this.engine.tips.debug(
              "[Update Object] Object Update: " + param + ":" + type
            );
          }
        } else {
          // 变量新增数据，必须采用vue的$set方法，更新可以直接响应。
          this.engine.vue.$set(object, param, update[param]);
          this.engine.tips.debug(
            "[Update Object] Object Insert: " + param + ":" + type
          );
        }
      }
      // this.engine.tips.debug("[Update Object] Object Parse: " + param + "，update type:" + type
      //   + ", original type" + checkPrototype.call(object[param]));
    }

    this.engine.tips.debug(
      "[Update Object] Updated:" + JSON.stringify(object) + ","
    );
  },
  findCell: function(data, name) {
    let find = $.grep(data, function(value) {
      return value.name == "name"; //筛选出类型ID数据，便于监听；
    });
    if (find.length == 1) {
      return find[0];
    } else {
      return null;
    }
  },
  // 翻译接口
  translate: function(text, from, to, callback) {
    let appid =
      this.engine.config.api.baidu.translate.appid || "20160719000025476"; // 百度开发者 翻译API KEY
    let key =
      this.engine.config.api.baidu.translate.key || "nh2h5OgnbJg2ccId1HhG";
    let salt = new Date().getTime();
    // 多个query可以用\n连接  如 query='apple\norange\nbanana\npear'
    let f = from;
    let t = to;
    let str1 = appid + text + salt + key;
    let sign = this.md5(str1).toLocaleLowerCase(); // 百度只接受小写的md5。

    // 下面要替换成八爪鱼自己的框架引擎
    this.engine.request.getJSONP(
      "https://api.fanyi.baidu.com/api/trans/vip/translate",
      {
        q: text,
        appid: appid,
        salt: salt,
        from: f,
        to: t,
        sign: sign
      },
      function(data) {
        // 如果有返回结果
        if (data.trans_result) {
          if (callback) {
            // 因为百度翻译API免费版设置了请求频次间隔。。。所以延迟1秒回调，相当于阻塞了。
            setTimeout(function() {
              callback(data.trans_result[0].dst);
            }, 1000);
          }
        }
      }
    );
  },
  // GPS坐标转换：https://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition
  // from：1：GPS标准坐标（wgs84）；2：搜狗地图坐标； 3：火星坐标（gcj02），即高德地图、腾讯地图和MapABC等地图使用的坐标；
  // 4：3中列举的地图坐标对应的墨卡托平面坐标; 5：百度地图采用的经纬度坐标（bd09ll）；6：百度地图采用的墨卡托平面坐标（bd09mc）;
  // 7：图吧地图坐标；8：51地图坐标；
  // to：3：火星坐标（gcj02），即高德地图、腾讯地图及MapABC等地图使用的坐标；
  // 5：百度地图采用的经纬度坐标（bd09ll）；6：百度地图采用的墨卡托平面坐标（bd09mc）；
  translateGPS(location, callback) {
    this.engine.request.getJSONP(
      "https://api.map.baidu.com/geoconv/v1/",
      {
        coords: location.longitude + "," + location.latitude,
        from: location.from || 1,
        to: location.to || 5,
        ak: this.engine.config.api.baidu.AK
      },
      function(data) {
        // alert(JSON.stringify(result));
        if (callback && data.result) {
          // 将转换好的经纬度返回给前端。
          callback({ longitude: data.result[0].x, latitude: data.result[0].y });
        }
      }
    );
  },
  // 该组件目前存在问题，修复以后 要取消 octopus.tools.weather 的注释，修改接口，从八爪鱼API处获取。
  weather: function(location, callback) {
    // let o = this;
    // https://dev.qweather.com/docs/api/weather/  // 和风天气 开发文档
    // https://github.com/qwd/WeatherIcon // 天气图标更新
    // let key = "9cdfdbf290bf431aa005d006091156a1";
    // 通过下列接口获取城市ID，但是也别用太多，还是写死吧。
    // https://geoapi.qweather.com/v2/city/lookup?location=上海&key=9cdfdbf290bf431aa005d006091156a1
    // https://devapi.qweather.com/v7/weather/now?location=101010100&key=9cdfdbf290bf431aa005d006091156a1

    // // 上海：101020100；北京：101010100；
    // if (city == '上海' || !city) {
    //   city = 101020100
    // }

    // https://blog.csdn.net/bhq2010/article/details/8565551 // 获取空气质量
    // https://aqicn.org/city/china/lasa/qufushezhan

    // https://www.cnblogs.com/dyhao/p/11942563.html // 国家气象局天气获取

    // this.engine.request.getJSON("http://www.weather.com.cn/data/cityinfo/101010100.html", function (data) {
    //   alert(JSON.stringify(data));
    // });

    // this.engine.request.getJSONP("http://www.weather.com.cn/data/cityinfo/101010100.html", null, function (data) {
    //   // 如果有返回结果
    //   alert(JSON.stringify(data));
    // });

    // 调用八爪鱼框架
    this.engine.request.api.post(
      "/ESB/Services/Tools/Weather/Get",
      location,
      // 处理回调事件，通过分析data.status.code的状态来实现。
      function(data) {
        callback(data);
      }
    );
  },
  // JSON 数据，排序依据的字段，类型：1：正序；2：降序
  sort: function(data, name, type) {
    data.sort(function(a, b) {
      if (a[name] > b[name]) {
        return type ? 1 : -1;
      }
      if (a[name] < b[name]) {
        return type ? -1 : 1;
      }
      return 0;
    });

    return data;
  },
  // 图像压缩
  imageCompress: function(data, callback) {
    let reader = new FileReader();
    //这里把一个文件用base64编码，使用readAsDataURL必须使用raw格式。
    reader.readAsDataURL(data.file.raw);
    reader.onload = function(e) {
      // 转换成base64编码
      let base64Data = e.target.result;
      // console.log("获取文件对象数据流：" + base64Data);
      // 创建Canvas对象(画布)
      let canvas = document.createElement("canvas");
      // 获取对应的CanvasRenderingContext2D对象(画笔)
      let context = canvas.getContext("2d");
      // 创建新的图片对象
      let img = new Image();
      // 指定图片的DataURL(图片的base64编码数据)
      img.src = base64Data;
      // 监听浏览器加载图片完成，然后进行进行绘制
      img.onload = () => {
        // 画面压缩 / 2，然后后面在将画质调整为0.8。
        let proportion = 0.0;
        // 得到720高的整体比例，如果高度占优势，则优化高度，如果宽度占优势，则优化宽度。
        if (img.height > img.width) {
          proportion = 1 - (img.height - data.size) / img.height;
        } else {
          proportion = 1 - (img.width - data.size) / img.width;
        }

        let imgHeight = img.height * proportion;
        let imgWidth = img.width * proportion;

        console.log(
          "原始：h:" +
            img.height +
            ", w:" +
            img.width +
            "; 压缩：h:" +
            parseInt(imgHeight) +
            ", w:" +
            parseInt(imgWidth) +
            "。"
        );

        // 指定canvas画布大小，该大小为最后生成图片的大小
        canvas.width = imgWidth;
        canvas.height = imgHeight;
        /* drawImage画布绘制的方法。(0,0)表示以Canvas画布左上角为起点，400，300是将图片按给定的像素进行缩小。
        如果不指定缩小的像素图片将以图片原始大小进行绘制，图片像素如果大于画布将会从左上角开始按画布大小部分绘制图片，最后的图片就是张局部图。*/
        context.drawImage(img, 0, 0, imgWidth, imgHeight);
        // 将绘制完成的图片重新转化为base64编码，file.file.type为图片类型，0.9为压缩质量。
        let base64DataCompress = canvas.toDataURL(data.file.type, data.quality);

        // Base64 转 File对象
        let arr = base64DataCompress.split(","),
          mime = arr[0].match(/:(.*?);/)[1],
          bstr = atob(arr[1]),
          n = bstr.length,
          u8arr = new Uint8Array(n);
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n);
        }
        let blobToFile = new Blob([u8arr], { type: mime });

        // 补充File对象信息
        blobToFile.lastModified = data.file.lastModified;
        blobToFile.lastModifiedDate = data.file.lastModifiedDate;
        blobToFile.name = data.file.name;

        console.log(
          "原始：" +
            parseInt(data.file.size / 1024 / 1024) +
            " MB，压缩：" +
            parseInt(blobToFile.size / 1024 / 1024) +
            " MB"
        );

        // 回调
        if (callback) {
          let blob2file = new window.File([blobToFile], blobToFile.name, {
            type: blobToFile.type
          });
          callback(blob2file);
        }
      };
    };

    // https://blog.csdn.net/guohao326/article/details/86382024   file to base64
    // 参考：https://www.cnblogs.com/007sx/p/7583202.html
  },
  // 调用OPEN API（ESB通用接口，直接免鉴权，并且后续可做服务器之间的白名单确保百分百安全）
  // 调用方式需要遵循 POST 方式，JSON数据格式。
  openAPI: function(path, param, callback) {
    // 把请求URL参数加入，此Key为必填。
    param.open_api_url = path;

    // 获取token参数
    let url_query = this.engine.router.get().query;

    // 定向拼接，后续需要做鉴权，需要实现。
    let access_token = "null";
    if (url_query["access_token"]) {
      access_token = url_query["access_token"];
    }
    let url =
      this.engine.config.url +
      "/ESB/Services/Tools/OpenAPI?access_token=" +
      access_token;
    // 调用八爪鱼Open Api框架
    this.engine.request.api.open(
      url,
      param,
      // 处理回调事件，通过分析data.status.code的状态来实现。
      function(data) {
        callback(data);
      }
    );
  },
  // 启动NFC扫描
  NFCStart: function() {
    if (window.webkit) {
      window.webkit.messageHandlers.NFCStart.postMessage(null);
    } else if (window.Android) {
      // 需要弹出遮罩，因为Android没有扫描。
      window.Android.NFCStart();
    }
  },
  QRScan: function() {
    if (window.QRStart) {
      window.QRStart();
    } else if (window.Android) {
      // 需要弹出遮罩，因为Android没有扫描。
      window.Android.QRStart();
    }
  },
  // 渐变色版
  gradients: function(name) {
    let data = { start: "", end: "" };
    if (name == "orange") {
      data.start = "#FF9D00";
      data.end = "#FF3232";
    } else if (name == "blue") {
      data.start = "#00dfe4";
      data.end = "#0076FF";
    } else if (name == "green") {
      data.start = "#31dd24";
      data.end = "#0e7a15";
    } else if (name == "purple") {
      data.start = "#d06bfa";
      data.end = "#871cd2";
    } else if (name == "yellow") {
      data.start = "#fae107";
      data.end = "#ffc339";
    } else if (name == "cyan") {
      data.start = "#86f3fa";
      data.end = "#0fc1d0";
    } else {
      data.start = name;
      data.end = name;
    }

    return data;
  },

  // 工具md5示例
  tool_md5: function() {
    md5(""); // d41d8cd98f00b204e9800998ecf8427e
    md5("The quick brown fox jumps over the lazy dog"); // 9e107d9d372bb6826bd81d3542a419d6
    md5("The quick brown fox jumps over the lazy dog."); // e4d909c290d0fb1ca068ffaddf22cbd0

    // It also supports UTF-8 encoding
    md5("中文"); // a7bac2239fcdcb3a067903d8077c4a07

    // It also supports byte `Array`, `Uint8Array`, `ArrayBuffer`
    md5([]); // d41d8cd98f00b204e9800998ecf8427e
    md5(new Uint8Array([])); // d41d8cd98f00b204e9800998ecf8427e

    // Different output
    md5(""); // d41d8cd98f00b204e9800998ecf8427e
    md5.hex(""); // d41d8cd98f00b204e9800998ecf8427e
    md5.array(""); // [212, 29, 140, 217, 143, 0, 178, 4, 233, 128, 9, 152, 236, 248, 66, 126]
    md5.digest(""); // [212, 29, 140, 217, 143, 0, 178, 4, 233, 128, 9, 152, 236, 248, 66, 126]
    md5.arrayBuffer(""); // ArrayBuffer
    md5.buffer(""); // ArrayBuffer, deprecated, This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.
  },
  tool_base64: function() {
    Dan.Base64.encode("dankogai"); // ZGFua29nYWk=
    Dan.Base64.encode("小飼弾"); // 5bCP6aO85by+
    Dan.Base64.encodeURI("小飼弾"); // 5bCP6aO85by-

    Dan.Base64.decode("ZGFua29nYWk="); // dankogai
    Dan.Base64.decode("5bCP6aO85by+"); // 小飼弾
    // note .decodeURI() is unnecessary since it accepts both flavors
    Dan.Base64.decode("5bCP6aO85by-"); // 小飼弾
  },
  // 小数点控制
  numberFormat: function(value, pIndex) {
    value = value || 0;
    pIndex = pIndex || 2;
    // 实现小数
    value = value.toFixed(pIndex || 2);
    // 实现千分位
    value = value.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, "$&,");

    return value;
  },
  thousands: function(num) {
    //千分位
    let str = num.toString();
    let reg =
      str.indexOf(".") > -1 ? /(\d)(?=(\d{3})+\.)/g : /(\d)(?=(?:\d{3})+$)/g;
    return str.replace(reg, "$1,");
  },
  //动态添加script标签
  loadScript: function(xyUrl, callback) {
    let head = document.getElementsByTagName("head")[0];
    let script = document.createElement("script");
    script.type = "text/javascript";
    script.src = xyUrl;
    //借鉴了jQuery的script跨域方法
    script.onload = script.onreadystatechange = function() {
      if (
        !this.readyState ||
        this.readyState === "loaded" ||
        this.readyState === "complete"
      ) {
        callback && callback();
        // Handle memory leak in IE
        script.onload = script.onreadystatechange = null;
        if (head && script.parentNode) {
          head.removeChild(script);
        }
      }
    };
    // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
    head.insertBefore(script, head.firstChild);
  },
  //  切换tab之后判断ifarme中的echarts不会变成宽度为100
  iframeRepair: function() {
    let isIframeRepair = false;
    let iframe = parent.document.querySelectorAll(`iframe`);
    for (let i = 0; i < iframe.length; i++) {
      if (iframe[i].src == location.href) {
        if (!iframe[i].parentNode.getAttribute("style")) {
          isIframeRepair = true;
          break;
        }
      }
    }
    if (iframe.length === 0) {
      isIframeRepair = true;
    }
    return isIframeRepair;
  },
  //生成随机数数组
  RndNum: function(n, l) {
    let rnd = [];
    for (let i = 0; i < n; i++)
      rnd[i] =
        l > 1
          ? Math.floor(Math.random() * (l - 1))
          : Math.floor(Math.random() * l);
    return rnd;
  },
  //分钟转换几天几时几分
  minuteFormat: function(StatusMinute) {
    let Minute = Math.round(StatusMinute);
    let day = parseInt(Minute / 60 / 24);
    let hour = parseInt((Minute / 60) % 24);
    let min = parseInt(Minute % 60);
    return {
      day: day,
      hour: hour,
      min: min
    };
  },
  //时间4等分
  timeInterval: function(startTime, endTime) {
    let start = new Date(startTime.replace(/-/g, "/")).getTime();
    let end = new Date(endTime.replace(/-/g, "/")).getTime();
    if (start == end) {
      return [this.dateFormat(new Date(start), "HH:mm")];
    } else {
      let interval = Math.round((end - start) / 3);
      let time1 = this.dateFormat(new Date(start), "HH:mm");
      let time2 = this.dateFormat(new Date(start + interval), "HH:mm");
      let time3 = this.dateFormat(new Date(start + interval * 2), "HH:mm");
      let time4 = this.dateFormat(new Date(end), "HH:mm");
      return [time1, time2, time3, time4];
    }
  },
  // 截取字符串
  abbreviationText: function(text, length) {
    if (text.length > length) {
      text = text.substring(0, length) + "...";
    }
    return text;
  },
  // 自动滚动函数
  autoScroll: function(dom, speed, delay, height) {
    // 设置可选参数
    speed = speed || 20; // 速度
    delay = delay || 3000; // 延迟间隔
    height = height || 30; // 每行高度

    //滚动效果
    // let scrollArea = document.getElementById(id);
    let scrollArea = dom;
    scrollArea.scrollTop = 0;
    setTimeout(() => {
      startScroll(scrollArea);
    }, delay);

    // 启动滚动
    function startScroll(scrollArea) {
      let timer = setInterval(() => {
        scrollUp(scrollArea, timer);
      }, speed);
      scrollArea.scrollTop++;
    }

    //
    function scrollUp(scrollArea, timer) {
      if (scrollArea.scrollTop % height == 0) {
        clearInterval(timer);
        setTimeout(() => {
          startScroll(scrollArea);
        }, delay);
      } else {
        scrollArea.scrollTop++;
        if (
          scrollArea.scrollTop >=
          scrollArea.scrollHeight - scrollArea.clientHeight - 20
        ) {
          setTimeout(() => {
            scrollArea.scrollTop = 0;
          }, delay);
        }
      }
    }
  },
  // 表单验证
  verify: function(form, rules) {
    // 非空条件验证
    for (let [k, v] of Object.entries(rules)) {
      // 条件验证
      if (typeof rules[k].reg === "function" && !rules[k].reg()) {
        this.engine.tips.warning(v.message);
        return false;
      }
      if (typeof rules[k].reg === "object" && !rules[k].reg.test(form[k])) {
        this.engine.tips.warning(v.message);
        return false;
      }

      if (v.required && oToolsEngine.prototype.isEmpty(form[k])) {
        this.engine.tips.warning(v.message);
        return false;
      }
    }
    return true;
  },

  isEmpty: function(v) {
    let bool = false;
    switch (typeof v) {
      case "string":
        bool = v === "";
        break;
      case "number":
        bool = v <= 0;
        break;
      case "object":
        if (v && v.length == 0) {
          bool = true;
        } else if (v && v.length > 0) {
          bool = v.map(x => x.mobile === "" || x.username === "")[0];
        }
        break;
    }
    return bool;
  }
};
export { oToolsEngine };
